package com.hm.order.service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hm.common.common.CommonUtil;
import com.hm.common.exception.ServiceException;
import com.hm.order.mongo.def.OrderOperationStatu;
import com.hm.order.mongo.def.OrderOwner;
import com.hm.order.mongo.def.OrderStatusOperation;
import com.hm.order.mongo.def.OrderTypeDef;
import com.hm.order.mongo.domain.Order;
import com.hm.order.mongo.domain.OrderItem;
import com.hm.order.mongo.domain.QOrderItem;
import com.hm.order.share.repository.OrderItemRepository;
import com.hm.order.share.repository.OrderRepository;
import com.hm.order.share.service.OrderStatusEngineService;
import com.hm.order.share.service.OrderStatusService;
import com.hm.order.vo.PlaceAnOrderVo;

/**
 * @author shishun.wang
 * @date 下午6:09:37 2016年7月15日
 * @version 1.0
 * @describe
 */
@Service
public class OrderStatusServiceImpl implements OrderStatusService {

	@Autowired
	private OrderRepository orderRepository;

	@Autowired
	private OrderItemRepository orderItemRepository;

	@Autowired
	private OrderStatusEngineService orderStatusEngineService;

	@Override
	public void placeAnOrder(OrderTypeDef orderType, List<PlaceAnOrderVo> placeAnOrders) {
		Order order = new Order();
		{
			order.setOrderType(orderType);
		}
		order = orderRepository.save(order);

		List<OrderItem> orderItems = new ArrayList<OrderItem>();
		for (PlaceAnOrderVo placeAnOrder : placeAnOrders) {
			OrderItem orderItem = new OrderItem();
			orderItem.setTargetId(placeAnOrder.getTargetId());
			orderItem.setNumbers(placeAnOrder.getNumbers());
			orderItem.setPrice(placeAnOrder.getPrice());
			orderItem.setTotalPrice(placeAnOrder.getPrice() * placeAnOrder.getNumbers());
			orderItem.setOperationStatu(
					orderStatusEngineService.nextStatus(OrderOwner.BUYER, null, OrderStatusOperation.PLACE_AN_ORDER));
			orderItem.setOrderId(order.getId());
			orderItem.setOrderNum(CommonUtil.getCodeNumber());

			orderItem = orderItemRepository.save(orderItem);
			orderItems.add(orderItem);
		}
		order = orderRepository.findOne(order.getId());
		order.setOrderItems(orderItems);
		orderRepository.save(order);
	}

	@Override
	public void cancelOrder(OrderTypeDef orderType, String orderItemId, String orderNum) {
		OrderItem orderItem = getOrderItem(orderItemId, orderNum);
		{
			OrderOperationStatu operationStatu = orderStatusEngineService.nextStatus(OrderOwner.BUYER,
					orderItem.getOperationStatu(), OrderStatusOperation.CANCEL_ORDER);
			orderItem.setOperationStatu(operationStatu);
		}
		orderItem = orderItemRepository.save(orderItem);
		refreshOrder(orderItem.getOrderId());
	}

	@Override
	public void deliveryed(OrderTypeDef orderType, String orderItemId, String orderNum) {
		OrderItem orderItem = getOrderItem(orderItemId, orderNum);
		{
			OrderOperationStatu operationStatu = orderStatusEngineService.nextStatus(OrderOwner.BUYER,
					orderItem.getOperationStatu(), OrderStatusOperation.DELIVERYED);
			orderItem.setOperationStatu(operationStatu);
		}
		orderItem = orderItemRepository.save(orderItem);
		refreshOrder(orderItem.getOrderId());
	}

	@Override
	public void salesReturn(OrderTypeDef orderType, String orderItemId, String orderNum) {
		OrderItem orderItem = getOrderItem(orderItemId, orderNum);
		{
			OrderOperationStatu operationStatu = orderStatusEngineService.nextStatus(OrderOwner.BUYER,
					orderItem.getOperationStatu(), OrderStatusOperation.SALES_RETURN);
			orderItem.setOperationStatu(operationStatu);
		}
		orderItem = orderItemRepository.save(orderItem);
		refreshOrder(orderItem.getOrderId());
	}

	@Override
	public void shipmentsed(OrderTypeDef orderType, String orderItemId, String orderNum) {
		OrderItem orderItem = getOrderItem(orderItemId, orderNum);
		{
			OrderOperationStatu operationStatu = orderStatusEngineService.nextStatus(OrderOwner.SELLER,
					orderItem.getOperationStatu(), OrderStatusOperation.SHIPMENTSED);
			orderItem.setOperationStatu(operationStatu);
		}
		orderItem = orderItemRepository.save(orderItem);
		refreshOrder(orderItem.getOrderId());
	}

	@Override
	public void deliveryedFinished(OrderTypeDef orderType, String orderItemId, String orderNum) {
		OrderItem orderItem = getOrderItem(orderItemId, orderNum);
		{
			OrderOperationStatu operationStatu = orderStatusEngineService.nextStatus(OrderOwner.SELLER,
					orderItem.getOperationStatu(), OrderStatusOperation.DELIVERYED_FINISHED);
			orderItem.setOperationStatu(operationStatu);
		}
		orderItem = orderItemRepository.save(orderItem);
		refreshOrder(orderItem.getOrderId());
	}

	@Override
	public void salesReturned(OrderTypeDef orderType, String orderItemId, String orderNum) {
		OrderItem orderItem = getOrderItem(orderItemId, orderNum);
		{
			OrderOperationStatu operationStatu = orderStatusEngineService.nextStatus(OrderOwner.SELLER,
					orderItem.getOperationStatu(), OrderStatusOperation.SALES_RETURNED);
			orderItem.setOperationStatu(operationStatu);
		}
		orderItem = orderItemRepository.save(orderItem);
		refreshOrder(orderItem.getOrderId());
	}

	private OrderItem getOrderItem(String orderItemId, String orderNum) {
		if (CommonUtil.isEmpty(orderItemId) && CommonUtil.isEmpty(orderNum)) {
			throw ServiceException.warn("订单ID、订单号不允许全部为null");
		}
		QOrderItem qOrderItem = QOrderItem.orderItem;

		OrderItem orderItem = null;
		if (CommonUtil.isNotEmpty(orderNum)) {
			orderItem = orderItemRepository.findOne(qOrderItem.orderNum.eq(orderNum));
		} else {
			orderItem = orderItemRepository.findOne(orderItemId);
		}
		if (null == orderItem) {
			throw ServiceException.warn("没有找到订单");
		}
		return orderItem;
	}
	
	private void refreshOrder(String orderId){
		QOrderItem qOrderItem = QOrderItem.orderItem;
		List<OrderItem> orderItems = new ArrayList<OrderItem>();
		Iterator<OrderItem> iterator = orderItemRepository.findAll(qOrderItem.orderId.eq(orderId)).iterator();
		while(iterator.hasNext()){
			orderItems.add(iterator.next());
		}
		
		Order order = orderRepository.findOne(orderId);
		if(null == order){
			throw ServiceException.warn("订单组没找到");
		}
		order.setOrderItems(orderItems);
		orderRepository.save(order);
	}
}
